# 闭包（Closure） 是指一个函数与其相关的引用环境（即外部作用域的变量）的组合。
# 当一个内部函数引用了外部函数的变量，并且外部函数已经执行完毕，但这些变量仍然被内部函数保留时，就形成了闭包。闭包的存在与否，取决于内部函数是否被外部保留并持续访问外部函数变量
# 闭包允许函数“记住”并访问其定义时的上下文环境。
# 简单闭包
def outer(logo):
    def inner(msg):
        print(f"<{logo}>{msg}<{logo}>")
    return inner
fn1 = outer("黑马程序员")
fn1("大家好")
fn2 = outer("传智教育")
fn2("大家好")
# 在闭包函数中(内部函数中)想要修改外部函数的变量值，需要使用nonlocal关键字声明这个外部变量
def outer1(num1):
    def inner1(num2):
        nonlocal num1
        num1 += num2
        print(num1)
    return inner1
fn = outer1(10)
fn(10)
# 使用闭包实现ATM小案例
def account_create(initial_amount=0):
    def atm(num, deposit=True):
        nonlocal initial_amount
        if deposit:
            initial_amount += num
            print(f"存款：+{num}，账号余额：{initial_amount}")
        else:
            initial_amount -= num
            print(f"取款：-{num}，账号余额：{initial_amount}")
    return atm
atm = account_create()
atm(100)
atm(200)
atm(100, deposit=False)
# 闭包的优点和缺点：
# 优点：不定义全局变量，也可以让函数持续访问和修改一个外部变量
# 优点：闭包函数(内部函数)引用的外部变量，是外层函数的内部变量。作用域封闭难以被误操作修改
# 缺点；额外的内存占用
